﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Reflection;
using Genewiz.MVC3.Models;
using Genewiz.Entity;
using Genewiz.DataAccess;

namespace Genewiz.MVC3.Controllers
{
    [Desc(Descriptor = "Role Maintainence Module")]
    public class RoleMaintainenceController : Controller
    {
        [Desc(Descriptor = "Maintain Role")]
        public ActionResult Index()
        {
            List<CtrlActionEntity> listAction = GetAllPermissionPointFromCode();
            List<UserInfoEntity> listUser = GetUserInfo();
            BindInitialData();

            return View(listAction);
        }

        [Desc(Descriptor = "Initialize Role")]
        public JsonResult InitializeRole()
        {
            //DataAccessBase.ExecuteNonQuery("DELETE FROM CtrlAction ");
            if (GetAllPermissionPointFromDb().Count > 0)
            {
                return Json("false", JsonRequestBehavior.AllowGet);
            }
            else
            {
                List<CtrlActionEntity> listAction = GetAllPermissionPointFromCode();
                List<CtrlActionEntity> listCtrlAct = new List<CtrlActionEntity>();
                foreach (var act in listAction)
                {
                    CtrlActionEntity ctrlAct = new CtrlActionEntity();
                    ctrlAct.ControllerName = act.ControllerName;
                    ctrlAct.ActionName = act.ActionName;
                    ctrlAct.ActDescription = act.ActDescription;
                    ctrlAct.IsAllowAllRole = act.IsAllowAllRole;
                    ctrlAct.CtrlDescription = act.CtrlDescription;
                    listCtrlAct.Add(ctrlAct);

                }

                DataAccessBase.Save(listCtrlAct, true);
                return Json("true", JsonRequestBehavior.AllowGet);
            }
        }

        /// <summary>
        /// Get all controllers and actions from Assembly
        /// </summary>
        /// <returns></returns>
        private List<CtrlActionEntity> GetAllPermissionPointFromCode()
        {
            Type[] tList = Assembly.GetExecutingAssembly().GetTypes()
                 .Where(x => x.IsClass && x.BaseType == typeof(Controller)).OrderBy(x => x.Name).ToArray();
            List<CtrlActionEntity> list = new List<CtrlActionEntity>();
            foreach (var t in tList)
            {
                MethodInfo[] methods = t.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
                    .Where(x => x.ReturnType == typeof(ActionResult) || x.ReturnType == typeof(JsonResult))
                    .OrderBy(x => x.Name).ToArray();

                object[] ta = t.GetCustomAttributes(typeof(DescAttribute), false).ToArray();
                DescAttribute desc = new DescAttribute();

                CtrlActionEntity caController = new CtrlActionEntity();
                caController.ControllerName = t.Name;
                caController.ActionName = t.Name;

                if (ta.Length > 0)
                {
                    desc = ta[0] as DescAttribute;
                    caController.IsAllowAllRole = desc.IsAllowAllRole;
                    caController.CtrlDescription = desc.Descriptor;
                    caController.ActDescription = desc.Descriptor;
                }
                else
                {
                    caController.IsAllowAllRole = false;
                    caController.CtrlDescription = "";
                    caController.ActDescription = "";
                }
                list.Add(caController);
                foreach (var m in methods)
                {
                    CtrlActionEntity ca = new CtrlActionEntity();
                    ca.ControllerName = t.Name;
                    ca.CtrlDescription = desc.Descriptor;
                    object[] obj = m.GetCustomAttributes(typeof(DescAttribute), false);
                    ca.ActionName = m.Name;
                    if (obj.Length > 0)
                    {
                        DescAttribute[] da = obj as DescAttribute[];
                        ca.ActDescription = da[0].Descriptor;
                        ca.IsAllowAllRole = da[0].IsAllowAllRole;
                    }
                    else
                    {
                        ca.ActDescription = "";
                        ca.IsAllowAllRole = false;
                    }
                    list.Add(ca);
                }

            }
            return list;
        }

        private List<CtrlActionEntity> GetAllPermissionPointFromDb()
        {
            List<CtrlActionEntity> listEntity = DataAccessBase.SelectAll<CtrlActionEntity>();
            return listEntity;
        }

        /// <summary>
        /// Get User Info list
        /// </summary>
        /// <returns></returns>
        private List<UserInfoEntity> GetUserInfo()
        {
            List<UserInfoEntity> listEntity = DataAccessBase.SelectAll<UserInfoEntity>();
            return listEntity;
        }

        /// <summary>
        /// Get all Role
        /// </summary>
        /// <returns></returns>
        private List<RoleEntity> GetAllRole()
        {
            List<RoleEntity> listEntity = DataAccessBase.SelectAll<RoleEntity>();
            return listEntity;
        }
        /// <summary>
        /// Initialize page data
        /// </summary>
        private void BindInitialData()
        {
            List<UserInfoEntity> listUser = GetUserInfo();
            List<SelectListItem> uList = new List<SelectListItem>();
            foreach (var u in listUser)
            {
                SelectListItem item = new SelectListItem();
                item.Text = u.UserName;
                item.Value = u.UserID.ToString();
                uList.Add(item);
            }
            ViewData["ListUser"] = uList;
            List<RoleEntity> listRole = GetAllRole();
            List<SelectListItem> roleList = new List<SelectListItem>();
            foreach (var r in listRole)
            {
                SelectListItem item = new SelectListItem();
                item.Text = r.RoleName;
                item.Value = r.RoleID.ToString();
                roleList.Add(item);
            }
            ViewData["maintainRole"] = roleList;

            ViewData["ListRole"] = listRole;

            List<CtrlActionEntity> listCtrlAct = GetAllPermissionPointFromDb();
            ViewData["ListControllerAction"] = listCtrlAct;

        }

        /// <summary>
        /// Save role
        /// </summary>
        /// <returns></returns>
        [Desc(Descriptor = "Save Role")]
        public JsonResult SaveRole(string uID, string uRole, string uRoleID)
        {
            bool flag = false;
            try
            {
                List<string> uroIDList = uRole.Split(',').ToList();
                List<string> roleIDList = uRoleID.Split(',').ToList();
                UserRoleEntity ure = new UserRoleEntity();
                ure.UserID = Convert.ToInt32(uID);
                List<UserRoleEntity> ureList = new List<UserRoleEntity>();
                ureList = DataAccessBase.Select(ure).Where(x => x.UserID == ure.UserID).ToList();
                if (DataAccessBase.Delete(ureList))
                {
                    ureList.Clear();
                    foreach (string rid in uroIDList)
                    {
                        UserRoleEntity e = new UserRoleEntity();
                        e.UserID = ure.UserID;
                        e.RoleID = Convert.ToInt32(rid);
                        ureList.Add(e);
                    }
                    DataAccessBase.Save(ureList, true);
                }

                UserCtrlActionEntity uce = new UserCtrlActionEntity();
                uce.UserID = Convert.ToInt32(uID);
                List<UserCtrlActionEntity> ucList = new List<UserCtrlActionEntity>();
                ucList = DataAccessBase.Select(uce).Where(x => x.UserID == uce.UserID).ToList();
                if (DataAccessBase.Delete(ucList))
                {
                    ucList.Clear();
                    foreach (string ucid in roleIDList)
                    {
                        UserCtrlActionEntity e = new UserCtrlActionEntity();
                        e.UserID = uce.UserID;
                        e.CtrlActionID = Convert.ToInt32(ucid);
                        ucList.Add(e);
                    }
                    DataAccessBase.Save(ucList, true);
                }
                flag = true;
            }
            catch (Exception)
            {

                flag = false;
            }
            return Json(flag, JsonRequestBehavior.AllowGet);
        }

        [Desc(Descriptor = "Update Role")]
        public JsonResult UpdateRole(string roleID, string actionID)
        {
            bool flag = false;
            try
            {
                int roid = Convert.ToInt32(roleID);
                List<string> roleIDList = actionID.Split(',').ToList();

                List<RoleCtrlActionEntity> actList = new List<RoleCtrlActionEntity>();
                RoleCtrlActionEntity r = new RoleCtrlActionEntity();
                r.RoleID = roid;
                actList = DataAccessBase.Select(r).Where(x => x.RoleID == r.RoleID).ToList();
                if (DataAccessBase.Delete(actList))
                {
                    actList.Clear();
                    foreach (string ucid in roleIDList)
                    {
                        RoleCtrlActionEntity e = new RoleCtrlActionEntity();
                        e.RoleID = roid;
                        e.CtrlActionID = Convert.ToInt32(ucid);
                        actList.Add(e);
                    }
                    DataAccessBase.Save(actList, true);
                    flag = true;
                }

            }
            catch (Exception)
            {

                throw;
            }
            return Json(flag, JsonRequestBehavior.AllowGet);
        }

    }
}
